package com.example.codegen;

import org.apache.commons.cli.CommandLine;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Optional;

import com.example.utils.Utils;

public class CodeGenJava {
    public static void main(String[] args) throws Exception {

        CommandLine cmd = Utils.parseCommandLineArgs(args);
        String inputDir = cmd.getOptionValue("input", "src/main/resources/guava");
        String outputDir = cmd.getOptionValue("output", "src/main/resources/java");

        if (!Utils.checkDirectoryExists(inputDir, "Input")) {
            System.exit(1);
        }
        if (!Utils.checkDirectoryExists(outputDir, "Output")) {
            System.exit(1);
        }

        System.out.println("Input Directory: " + inputDir);
        System.out.println("Output Directory: " + outputDir);

        String kLassPath = inputDir + "/MainClasses.txt";
        String dSLProgramPath = inputDir + "/dslProgram.txt";
        String dslInitPath = inputDir + "/";
        String outputMainPath = outputDir + "/Main.java";

        try {
            Type.disableInterface = false;
            BufferedWriter writer = new BufferedWriter(new FileWriter(outputMainPath));
            BufferedReader klassReader = new BufferedReader(new FileReader(kLassPath));
            BufferedReader dSLProgramReader = new BufferedReader(new FileReader(dSLProgramPath));
            writer.write("import java.util.ArrayList;\n" +
                    "import java.util.concurrent.*;\n");
            // test is klassReader is empty without readline
            Optional<Klass> klass = Optional.empty();
            do {
                klass = Parser.parserKlass(klassReader);
                if (klass.isPresent()) {
                    Klass k = klass.get();
                    writer.write(k.toJava());
                    writer.newLine();
                }
            } while (klass.isPresent());
            writer.newLine();
            Type.disableInterface = true;

            writer.write("public class Main {");
            writer.newLine();
            Optional<Method> program = Optional.empty();
            do {
                program = Parser.parserMethod("", dSLProgramReader);
                if (program.isPresent()) {
                    Method m = program.get();
                    writer.write(m.toJava());
                    writer.newLine();
                }
            } while (program.isPresent());
            writer.write("}");
            writer.newLine();
            writer.close();
            klassReader.close();
            dSLProgramReader.close();

            // find all Main*.txt files expect MainClasses.txt in dslInitPath
            // for each file, generate a Main*.java file under outputJavaDir using parserKlass
            Optional<Klass> klassInit = Optional.empty();
            for (String file : new java.io.File(dslInitPath).list()) {
                if (file.startsWith("Main") && file.endsWith(".txt") && !file.equals("MainClasses.txt")) {
                    BufferedReader klassInitReader = new BufferedReader(new FileReader(dslInitPath + file));
                    String outputInitPath = outputDir + "/" + file.replace(".txt", ".java");
                    writer = new BufferedWriter(new FileWriter(outputInitPath));
                    do {
                        klassInit = Parser.parserKlass(klassInitReader);
                        if (klassInit.isPresent()) {
                            Klass k = klassInit.get();
                            writer.write(k.toJava());
                            writer.newLine();
                        }
                    } while (klassInit.isPresent());
                    writer.close();
                    klassInitReader.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
